/**
 * \par Copyright (C) MakeBlock
 * @file    Ring_Buf.c
 * @author  MakeBlock
 * @brief   环形缓冲区
 *                  
 *
 * \par History:
 * <pre>
 *  作者         时间                    描述
 * hawis.qin     2020/01/09              创建新文件
 * </pre>
 */
 
#include "Ring_Buf.h"
#include "string.h"
#include "stdbool.h"

///////////////////////////////////////////////////////////////////////////////////////////////
// Realize public interface.

/**
***********************************************************************************************
* @brief       初始化环形缓冲区
* @details     无
* @param[in]   RING_BUF_DEF_STRUCT* ring_buf：环形缓冲区, uint8_t* src_buf：数据存储区, uint32_t src_buf_maxsize：数据存储区大小
* @param[out]  无
*
* @return     无
***********************************************************************************************
* @note   无。
***********************************************************************************************
*/
void RingBuf_Init(RING_BUF_DEF_STRUCT* ring_buf, uint8_t* src_buf, uint32_t src_buf_maxsize)
{
  ring_buf->write_index = 0;
  ring_buf->read_index = 0;  
  ring_buf->last_write_index = 0;
  ring_buf->last_read_index = 0;
  ring_buf->lock_read_index = 0;  
  ring_buf->lock_flag = false;  
  ring_buf->buff_addr = src_buf;
  ring_buf->max_size_mask = (src_buf_maxsize - 1);
}

/**
***********************************************************************************************
* @brief       读取环形缓冲区数据
* @details     无
* @param[in]   RING_BUF_DEF_STRUCT* src_ringbuf：环形缓冲区, uint32_t len：需要读取的数据长度
* @param[out]  uint8_t* dst_buf：输出数据缓冲区
*
* @return     实际读取到的数据长度
***********************************************************************************************
* @note   无。
***********************************************************************************************
*/
uint32_t RingBuf_Read(RING_BUF_DEF_STRUCT* src_ringbuf, uint32_t len, uint8_t* dst_buf)
{
  uint32_t count = 0;

  uint32_t buflen = RingBuf_Count(src_ringbuf);
  if(buflen<len)
  {
    len = buflen;
  }

  if(src_ringbuf->buff_addr != NULL)  
  {
    //if(!src_ringbuf->lock_flag)
    //{
        for (count = 0; count<len;count++)
        {
        dst_buf[count] = src_ringbuf->buff_addr[src_ringbuf->read_index++];
        src_ringbuf->read_index = (src_ringbuf->read_index&src_ringbuf->max_size_mask);
        }
    //}
    //else
    //{
    //    for (count = 0; count<len;count++)
    //    {
    //    dst_buf[count] = src_ringbuf->buff_addr[src_ringbuf->lock_read_index++];
    //    src_ringbuf->lock_read_index = (src_ringbuf->lock_read_index&src_ringbuf->max_size_mask);
    //    }
    //}

  }
  else
  {
    len = 0;
  }
	
	return len;
}

void RingBuf_Peek (RING_BUF_DEF_STRUCT* src_ringbuf, uint32_t len , uint8_t* dst_buf)
{
  uint32_t count = 0;

  uint32_t buflen = RingBuf_Count(src_ringbuf);
  if(buflen<len)
  {
    len = buflen;
  }
    
  if(src_ringbuf->buff_addr != NULL)  
  {
    for (count = 0; count<len;count++)
    {
      dst_buf[count] = src_ringbuf->buff_addr[src_ringbuf->peek_index++];
      src_ringbuf->peek_index = (src_ringbuf->peek_index&src_ringbuf->max_size_mask);
    }
  }
 else
 {
   // add error process
 }
}

void RingBuf_Peeked_Flush(RING_BUF_DEF_STRUCT* src_ringbuf)
{
	//if (!src_ringbuf->lock_flag)
	//{
		src_ringbuf->read_index = src_ringbuf->peek_index;
	//}
	//else
	//{
	//	src_ringbuf->lock_read_index = src_ringbuf->peek_index;
	//}
}

void RingBuf_Peeked_Reset (RING_BUF_DEF_STRUCT* src_ringbuf)
{
    //if(!src_ringbuf->lock_flag)
    //{
        src_ringbuf->peek_index = src_ringbuf->read_index;
    //}
    //else
    //{
    //    src_ringbuf->peek_index = src_ringbuf->lock_read_index;
    //}

}



/**
***********************************************************************************************
* @brief       写入数据到环形缓冲区
* @details     无
* @param[in]   RING_BUF_DEF_STRUCT* src_ringbuf：环形缓冲区, uint8_t* src：数据缓冲区, uint32_t len：需要读取的数据长度
* @param[out]  无
*
* @return     实际写入的数据长度
***********************************************************************************************
* @note   无。
***********************************************************************************************
*/
bool RingBuf_Write(RING_BUF_DEF_STRUCT* des_ringbuf, uint8_t* src, uint32_t len)
{
	if(len>RingBuf_UnusedCount(des_ringbuf))
	{
		return false;
	}
	if((des_ringbuf->write_index + len) <= (des_ringbuf->max_size_mask+1))
	{
		memcpy(des_ringbuf->buff_addr+des_ringbuf->write_index,src,len);
		des_ringbuf->write_index += len;
	}
	else
	{
		uint32_t len1 = des_ringbuf->max_size_mask + 1 - des_ringbuf->write_index;
		memcpy(des_ringbuf->buff_addr+des_ringbuf->write_index,src,len1);
		memcpy(des_ringbuf->buff_addr,src+len1,len - len1);
		des_ringbuf->write_index = len - len1;
	}
	return true;
}

/**
***********************************************************************************************
* @brief       环形缓冲区剩余长度
* @details     无
* @param[in]   RING_BUF_DEF_STRUCT* src_ringbuf：环形缓冲区
* @param[out]  无
*
* @return     剩余长度
***********************************************************************************************
* @note   无。
***********************************************************************************************
*/
uint32_t  RingBuf_UnusedCount(RING_BUF_DEF_STRUCT* src_ringbuf)
{
	if(src_ringbuf == NULL)
	{
		return 0;
	}
	//if (!src_ringbuf->lock_flag)
	//{
	//	return (src_ringbuf->max_size_mask - RingBuf_Count(src_ringbuf));
	//}
	//else
	//{
	//	return (src_ringbuf->max_size_mask - ((src_ringbuf->write_index - src_ringbuf->read_index) & src_ringbuf->max_size_mask) );
	//}
		if (!src_ringbuf->lock_flag)
		{
			return (src_ringbuf->max_size_mask - ((src_ringbuf->write_index - src_ringbuf->read_index) & src_ringbuf->max_size_mask));
		}
		else
		{
			return (src_ringbuf->max_size_mask - ((src_ringbuf->write_index - src_ringbuf->last_read_index) & src_ringbuf->max_size_mask));
		}
}

/**
***********************************************************************************************
* @brief       环形缓冲区数据长度
* @details     无
* @param[in]   RING_BUF_DEF_STRUCT* src_ringbuf：环形缓冲区
* @param[out]  无
*
* @return     数据长度
***********************************************************************************************
* @note   无。
***********************************************************************************************
*/
uint32_t RingBuf_Count(RING_BUF_DEF_STRUCT* src_ringbuf)
{
	uint32_t count = 0;
	if(src_ringbuf == NULL)
	{
		return 0;
	}

	//if (!src_ringbuf->lock_flag)
	//{
		//if (src_ringbuf->write_index >= src_ringbuf->read_index)
		//{
		//	count = (src_ringbuf->write_index - src_ringbuf->read_index) & (src_ringbuf->max_size_mask);
		//}
		//else
		//{
		//	count = (src_ringbuf->max_size_mask + 1) - (src_ringbuf->read_index - src_ringbuf->write_index);
		//}
		count = (src_ringbuf->write_index - src_ringbuf->read_index) & (src_ringbuf->max_size_mask);
	//}
	//else
	//{
	//	//if (src_ringbuf->write_index >= src_ringbuf->lock_read_index)
	//	//{
	//	//	count = (src_ringbuf->write_index - src_ringbuf->lock_read_index) & (src_ringbuf->max_size_mask);
	//	//}
	//	//else
	//	//{
	//	//	count = (src_ringbuf->max_size_mask + 1) - (src_ringbuf->lock_read_index - src_ringbuf->write_index);
	//	//}

	//	count = (src_ringbuf->write_index - src_ringbuf->lock_read_index)& (src_ringbuf->max_size_mask);
	//}


	return count;
}

void  RingBuf_Flush(RING_BUF_DEF_STRUCT* src_ringbuf)
{
	if(src_ringbuf == NULL)
	{
		return;
	}
	src_ringbuf->write_index = 0;
	src_ringbuf->read_index = 0;
	src_ringbuf->peek_index = 0;
}

uint32_t  RingBuf_Peeked_Counter(RING_BUF_DEF_STRUCT* src_ringbuf)
{
	uint32_t count;
	count = (src_ringbuf->peek_index-src_ringbuf->read_index)&(src_ringbuf->max_size_mask);
	return count;
}

uint32_t  RingBuf_PeekCount(RING_BUF_DEF_STRUCT* src_ringbuf)
{
	uint32_t count = 0;
	count = (src_ringbuf->write_index - src_ringbuf->peek_index)&(src_ringbuf->max_size_mask);
	return count;
}

void RingBuf_Peek_Pos_Change(RING_BUF_DEF_STRUCT* src_ringbuf, uint32_t offset)
{
	//if (!src_ringbuf->lock_flag)
	//{
		src_ringbuf->peek_index = (src_ringbuf->read_index + offset) & (src_ringbuf->max_size_mask);
	//}
	//else
	//{
	//	src_ringbuf->peek_index = (src_ringbuf->lock_read_index + offset) & (src_ringbuf->max_size_mask);
	//}
}

void RingBuf_ReadIndex_Change(RING_BUF_DEF_STRUCT* src_ringbuf, uint32_t offset)
{
    //if(!src_ringbuf->lock_flag)
    //{   
        src_ringbuf->read_index = (src_ringbuf->read_index+offset)&(src_ringbuf->max_size_mask);
    //}
    //else
    //{
    //    src_ringbuf->lock_read_index = (src_ringbuf->lock_read_index+offset)&(src_ringbuf->max_size_mask);
    //}
	
}


void RingBuf_Up_Lock(RING_BUF_DEF_STRUCT* src_ringbuf) //锁数据开启，并保存相关的索引
{
	src_ringbuf->lock_length = RingBuf_Count(src_ringbuf);
	src_ringbuf->lock_flag = true;
	src_ringbuf->last_read_index = src_ringbuf->read_index;
	src_ringbuf->last_write_index = src_ringbuf->write_index;
	src_ringbuf->read_index = src_ringbuf->last_write_index;
}

void RingBuf_Free_Lock(RING_BUF_DEF_STRUCT* src_ringbuf) //
{
	src_ringbuf->lock_flag = false;
	src_ringbuf->lock_length = 0;
	src_ringbuf->read_index = src_ringbuf->last_read_index;
	src_ringbuf->write_index = src_ringbuf->last_write_index;
}

bool RingBuf_Is_Lock(RING_BUF_DEF_STRUCT* src_ringbuf)
{
	return src_ringbuf->lock_flag;
}